using System;
using System.Collections.Generic;
using System.Linq;
using Web.HelperClasses;
using NHibernate;
using NHibernate.Criterion;
using Web.HelperClasses.AvatarService;

namespace Web.Model
{
	public enum ProjectCompletionApproval
	{
		Unknown = 0,

		Approved = 1,

		Denied = 2
	}

    public class Project : Entity, IPhotoContainer, ICommentable, IOwnable
	{
		public Project()
		{
			HeadComments = new List<HeadComment>();
			Photos = new List<Photo>();
			Vacancies = new List<Vacancy>();
		}

		public User Organizer { get; set; }

		public string Name { get; set; }

		public string ShortDescription { get; set; }
		
		public string Description { get; set; }

		public DateTime? Beginning { get; set; }

		public DateTime? Ending { get; set; }

        public bool IsHidden { get; set; }

		public IList<Vacancy> Vacancies { get; set; }

        public IList<HeadComment> HeadComments { get; set; }

		public Avatar ProjectAvatar { get; set; }

        public IList<Photo> Photos { get; set; }

		public ProjectCompletionApproval CompletionApproval { get; set; }

        public string AlbumName
        {
            get
            {
                return String.Format("{0} (#{1})", Name, Id);
            }
        }

	    public IEnumerable<User> Participants
	    {
	        get
	        {
                return  Vacancies.SelectMany(x => x.UsersApproved).Distinct();
	        }
	    }

		public bool IsCompleted
		{
			get { return IsFinished && Participants.Any() && CompletionApproval == ProjectCompletionApproval.Approved; }
		}

		public bool IsFinished
		{
			get { return Ending.HasValue && Ending.Value < DateTime.Now; }
		}

		public bool IsUpcomingOrInProgress
		{
			get { return Ending == null || Ending > DateTime.Now; }
		}

        public bool IsParticipating(User user)
        {
            return Organizer == user || Vacancies.Where(v => v.UsersApproved.Contains(user)).Any();
        }

        public bool IsVisibleToUser(User user)
        {
            return IsCompleted && (!IsHidden || (user != null && (user.IsAdmin || Organizer.Id == user.Id)))
				|| CompletionApproval == ProjectCompletionApproval.Unknown && (!IsFinished || (user != null && (user.IsAdmin || Organizer.Id == user.Id)));
        }

        public void Clear(ISession session)
        {
            Vacancies.ToList().ForEach(v => { v.RemoveAllUsers(); session.Delete(v); });
            YandexFotki yandexFotki = YandexFotki.GetInstance();
            Photos.ToList().ForEach(photo => { yandexFotki.Delete(photo); session.Delete(photo); });
            AvatarService avatarService = new ProjectAvatarService(session, yandexFotki);
            if (ProjectAvatar != null)
            {
                avatarService.RemoveAvatar(ProjectAvatar);
                ProjectAvatar = null;
            }
            var HeadComments = session.CreateCriteria<HeadComment>()
                .Add(Restrictions.Eq("Story", this))
                .List<HeadComment>();
            HeadComments.ToList().ForEach(c => { c.Clear(session); session.Delete(c); });

            session.Save(this);
        }

        public bool CanUpload(User user)
        {
            return user != null && (user.IsAdmin || IsParticipating(user)); 
        }

        public bool CanDelete(User user)
        {
            return user != null && (user.IsAdmin || user.Id == Organizer.Id); 
        }

        public User getOwner()
        {
            return this.Organizer;
        }

        public void NotifyNewComment(ISession session, CommentBase newComment)
        {
            ProjectNotifier notifier = new ProjectNotifier(Id, session);
            notifier.NotifyNewComment(newComment);
        }
	}
}